//using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;

namespace JcomTesters
{
    public class TsTool
    {
        public string GetName<T>() where T : Ab1Tester
        {
            var tname = typeof(T).Name;
            return tname.Substring(0, tname.Length - 6);
        }
        public string GetCurAppDir()
        {
            return AppDomain.CurrentDomain.BaseDirectory; //return Environment.CurrentDirectory;
        }
        public string GetCurWorkDir()
        {
            return Environment.CurrentDirectory;
        }
        public IEnumerable<Type> GetTesterTypes(string name = null)
        {
            var namespace1 = typeof(TsTool).Namespace;
            var sa2_start = namespace1 + ".Releases.";
            var sa2_end = "Cmd";

            if (string.IsNullOrEmpty(name))
            {
                var types = Assembly.GetExecutingAssembly().GetTypes().Where(x =>
                    !x.IsAbstract
                    && (
                    x.FullName.StartsWith(sa2_start, StringComparison.CurrentCultureIgnoreCase)
                    && x.FullName.EndsWith(sa2_end)
                    && x.FullName.Substring(sa2_start.Length, x.FullName.Length - sa2_start.Length - sa2_end.Length).IndexOf("+") == -1
                    )
                ).ToList();
                return types;
            }
            else
            {
                return System.Reflection.Assembly.GetExecutingAssembly().GetTypes().Where(x =>
                    !x.IsAbstract
                    && (
                    x.FullName.Equals(sa2_start + name + sa2_end, StringComparison.CurrentCultureIgnoreCase)
                    )
                ).ToList();
            }
        }

        public void echo(params object[] olist)
        {
            echoJoin("", olist);
        }
        public void echoJoin(string sp,params object[] olist)
        {
            var list = new List<string>();
            list.AddRange(olist.Select(o => o.ToString()));
            Console.WriteLine(string.Join(sp,list));
        }
        public void echoFormat(string format, params object[] pars)
        {
            Console.WriteLine(string.Format(format, pars));
        }

        public void DoMain(Type propType, string[] args)
        {
            if (propType.Name != "Program") { Console.WriteLine("不是 Program 自动退出了"); return; }

            var arg0 = "";//参数
            if (args == null || args.Length == 0 || string.IsNullOrEmpty(args[0]))
            {
                arg0="help";
            }
            else { arg0 = args[0]; }
            var type1 = this.GetTesterTypes(arg0).FirstOrDefault();
            if (type1 == null)
            {
                Console.WriteLine("cmd not found " + arg0);
                return;
            }
            var tester = Activator.CreateInstance(type1) as Ab1Tester;
            if (tester == null)
            {
                Console.WriteLine("cmd 继承错误");
                return;
            }
            tester.jtool = this;
            var args_new = new List<string>(args);
            if (args_new.Count > 0) args_new.RemoveAt(0);
            var a1 = tester.GetType().GetCustomAttribute(typeof(jDescAttribute)) as jDescAttribute;
            if (a1 != null && a1.IsDelete)
            {
                Console.WriteLine("已弃用");
                return;
            }
            try
            {
                tester.Run(args_new.ToArray());
            }
            catch (Exception ex)
            {
                Console.WriteLine("错误E7 " + ex.Message);
            }
        }
    }
    public class jDescAttribute : Attribute
    {
        public string Name { get; set; }
        public string Desc { get; set; }
        //示例
        public string Examples { get; set; }
        /// <summary>已完成测试</summary>
        public bool IsOk { get; set; }
        public jDescAttribute(string name, bool ok = false, string desc = null, string[] args = null)
        {
            this.Name = name;
            this.IsOk = ok;
            this.Desc = desc;
            this.Args = args;
        }
        //public list<>参数： name  desc
        public string[] Args { get; set; }
        public bool IsDelete { get; set; }
        //Obsolete
    }
    public class jException : Exception
    {
        public string jcode = "";
        public jException(string message, string jcode = "") : base(message)
        {
            this.jcode = jcode;
        }
    }
    public class jThrow
    {
        public static void whenNull(object o, string msg1 = "")
        {
            if (o == null) throw new jException(msg1);
        }
        public static void whenNotEquals(string s1, string s2, string msg1 = "")
        {
            if (s1 != s2) throw new jException(msg1);
        }
        public static void whenTrue(bool b, string msg1 = "")
        {
            if (b) throw new jException(msg1);
        }
        public static void whenFalse(bool b, string msg1 = "")
        {
            if (!b) throw new jException(msg1);
        }

        public static void whenEmpty(string s, string msg1 = "")
        {
            if (string.IsNullOrEmpty(s)) throw new jException(msg1);
        }
        public static void whenZero(int num, string msg = "")
        {
            if (num == 0) throw new jException(msg);
        }
        public static void whenNotInArray(Array arr, object o, string msg1 = "")
        {
            if (Array.IndexOf(arr, o) == -1) throw new jException(msg1);
        }
        public static void fail(string msg)
        {
            throw new jException(msg);
        }
    }
}